home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d3 / e40ds3.arc / API.DOC next >
Text File  |  1989-03-10  |  24KB  |  555 lines

  1.  
  2.  
  3.                   ┌────────────────────────────────────┐
  4.                   │E! APPLICATION PROGRAMMING INTERFACE│
  5.                   │                                    │
  6.                   │        PROGRAMMER'S GUIDE          │
  7.                   └────────────────────────────────────┘
  8.  
  9.  
  10. A . INTRODUCTION
  11. ****************
  12.  
  13.  
  14.            The  E!  application  programming  interface allows you to write
  15.       programs  that  directly  use  E!  functions  or modify E! variables.
  16.       Since  E!  is  an  "in-memory-only"  editor, it was a real concern to
  17.       provide  the  user  with  such an interface without using much memory
  18.       space.  Moreover,  it  was  important  to  find  a way to program new
  19.       functions  or  E!  "add-in" without requiring the programmer to learn
  20.       a  new  language  such as the Brief macro language. Then I decided to
  21.       allow  the  programmer  to write such programs with its own and usual
  22.       language whatever it could be (Pascal,  C,  etc..).
  23.  
  24.            To  achieve  this goal I wrote a built-in interrupt handler thru
  25.       which  the  user  may  call  E!  functions,  modify  E! variables and
  26.       flags,  access  specific  values  FROM  WITHIN  an  external  program
  27.       executing  while  E!  is  present  in memory. That is, from a program
  28.       loaded  from  the  E!  command  line.  This program will typically be
  29.       loaded  using  the  "@"  prefix  so  that  it  executes  as a "blind"
  30.       command and that the DOS screen has not to be displayed.
  31.  
  32.            With  the  E!  API you can now write a program, say myaddin.exe,
  33.       that  will  be  called  from  the E! command line (@myaddin) and that
  34.       can  execute  a  E!  command  such  as moving the cursor, marking and
  35.       manipulating blocks or modifying flags or variables.
  36.  
  37.            This   program   may  be  a  full-featured  MENU  that  executes
  38.       functions  without  having  to  remember  the required keystroke or a
  39.       program  that  performs  a  special job on the current text flow. You
  40.       can do almost anything you want using the E! API.
  41.  
  42.            This  approach  has  many  advantages.  First,  it is not memory
  43.       consuming  since  the  memory  space  used by the program is released
  44.       when  the  program  finishes.  Then you can use any language to write
  45.       an  API  program.  Nothing  new  to  learn.  You  just  have to use a
  46.       language  that  can  issue  software  interrupts  and  load  the  cpu
  47.       registers  with  the  appropriate  values.  Another advantage is that
  48.       the  size  of  the  E!.EXE file remains almost unchanged after adding
  49.       the API.
  50.  
  51.            The  main  difference  with  previous  E! versions is the way E!
  52.       manages  memory  space  when  it calls a child process. This makes no
  53.       difference for the user.
  54.  
  55.  
  56.  
  57. B. THE E! API INTERRUPT
  58. ***********************
  59.  
  60.            When  E!  is  first  loaded it traps interrupt C0h and redirects
  61.       it  to  an  internal  interrupt  handler.  This  handler analyzes any
  62.       request  addressed  to  it  thru  INT  C0h  and  performs  any action
  63.       requested. It then returns to the calling program.
  64.  
  65.            Interrupt  C0h  is normally an unused interrupt vector. If there
  66.       is  any  conflict  with  existing hardware or software you may change
  67.       this  interrupt  number  adding  the  following  line  in your active
  68.       PROFILE
  69.  
  70.            INTERRUPT n
  71.  
  72.            where  n  is  the  interrupt  number  (decimal)  you want to use
  73.       instead of C0h.
  74.  
  75.        ┌─────────────────────────────────────────────────────────────────┐
  76.        │WARNING:                                                         │
  77.        │                                                                 │
  78.        │     IF YOU ALREADY COMPILED API PROGRAMS THAT USE INTERRUPT C0h │
  79.        │ OR  ANY  OTHER VALUE, THESE PROGRAMS WILL FAIL TO RUN WITH THIS │
  80.        │ NEW  INTERRUPT  NUMBER  (i.e. P!.EXE)  UNLESS  YOU  PATCH THEM. │
  81.        │ ANOTHER  WAY  TO  HAVE  THEM WORKING IN ANY CASE IS TO TEST THE │
  82.        │ E!PRESENT ENVIRONMENT VARIABLE (SEE BELOW).                     │
  83.        └─────────────────────────────────────────────────────────────────┘
  84.  
  85.            Please,  use  this  feature  only  in  case  of  very particular
  86.       problems or needs.
  87.  
  88.            Be  aware  that calling INT C0h when E! is not present in memory
  89.       will  likely  cause  a  system crash. To detect E! presence from your
  90.       API   program  you  only  have  to  test  the  E!PRESENT  environment
  91.       variable  which  must  yield  192  if  E!  uses the default interrupt
  92.       vector  or  any  other  value  if  you  changed  it.  Only  E!  child
  93.       processes  can  see  this  variable.  So this is a secure way to make
  94.       sure  INT  C0  has  been  installed. If E! is not present (or no more
  95.       present)  this  environment  variable  does  not  exist  (unless  you
  96.       create  it).  Only  the  E!  child  processes  are  able  to see this
  97.       environment variable.
  98.  
  99.                              ┌─────────────┐
  100.                              │E!PRESENT=192│
  101.                              └─────────────┘
  102.  
  103.            The  value  of  the  EPRESENT  environment  variable  is changed
  104.       dynamically whenever a new PROFILE containing a new INTERRUPT command
  105.       is  loaded.  So, if your API program tests this value it will execute
  106.       safely.
  107.  
  108.  
  109.       E! API INTERRUPT SERVICES
  110.       *************************
  111.  
  112.            You  may  call the E! API interrupt to perform 7 kinds of tasks.
  113.       The  task  E! API will execute depends on the value you put in the AH
  114.       register  when you call INT C0h. If AH is not set to a right value an
  115.       error code (FFh) is returned in AL.
  116.  
  117.  
  118.       1/ Calling a E! function - AH = 0
  119.       _________________________________
  120.  
  121.            Calling  INT  C0h  with AH set to 0 will execute the E! function
  122.       which  code is loaded in BX. This code will be the same function code
  123.       described  in  the  E! documentation for macros. See also the API.PAS
  124.       unit for this description.
  125.  
  126.  
  127.            MOV   AH, 0
  128.            MOV   BX, 5
  129.            INT   C0h
  130.  
  131.            will  clear  the  current line from the cursor to the end of the
  132.       line.
  133.  
  134.            So you can activate up to 108 basic E! functions.
  135.  
  136.            Passing  a  function code > 32 or < 256 will be interpreted as a
  137.       normal  character  entry.  Though  it  is  not  an  efficient  way of
  138.       writing  a  string  to  E!.  You may want to use the Editbuffer to do
  139.       this.
  140.  
  141.            Function  code  27 (Escape) will be ignored and no error will be
  142.       returned.
  143.  
  144.            The  return  code of the function is always returned in AL. This
  145.       value  will  be  identical  to  the  error  codes described in the E!
  146.       documentation or 0 or 99 if the operation succeeded. See E!.DOC.
  147.  
  148.  
  149.  
  150.       2/ Requesting internal addresses - AH = 1 to 7
  151.       ______________________________________________
  152.  
  153.            The  E!  API  allows  you  to  access  and  modify  internal  E!
  154.       variables.  Actually  the E! API will return the address of variables
  155.       blocks  which  structure is described below for each call from AH = 1
  156.       to  AH  =  7.  The  block  address  is  always  returned in the ES:BX
  157.       registers  pair.  There  is  no  return  code  and AL is undefined on
  158.       exit.
  159.  
  160.  
  161.       AH = 1
  162.       ******
  163.  
  164.            On  return  ES:BX  contains  the  address  of the E! EditBuffer.
  165.       When  you  are  editing  a line in E! the actual text is not modified
  166.       until  you  leave  the  line  (or the file) or execute a E! function.
  167.       This  is  why  you can retrieve the previous content of the line when
  168.       you  hit  F9.  Any  modification  made to the EditBuffer is stored to
  169.       the  actual  text  when  the cursor leaves the current line or when a
  170.       function is executed that needs to have the EditBuffer stored.
  171.  
  172.            The  E!  Editbuffer is a 255 characters string. This is a Pascal
  173.       string.  So  the first byte contains the length of the string and the
  174.       string  actually  begins  with the second byte. Space is reserved for
  175.       255 characters + 1 length byte.
  176.  
  177.            The  return  code of the function is always returned in AL. This
  178.       value  will  be  identical  to  the  error  codes described in the E!
  179.       documentation. See E!.DOC.
  180.  
  181.            Modifying  the  EditBuffer  will  result  in  no  action  on the
  182.       screen  (see  AH  =  9).  This will not modify the actual text unless
  183.       you  leave  the  current line, call a E! function or call the special
  184.       "store  edit  line"  service  with  AH  =  12.  Be aware that certain
  185.       functions  acting  only  the  current  line  (hence on the editbuffer
  186.       only) will not store the editbuffer to the actual text.
  187.  
  188.            Do  not  forget  to  update  the  EditBuffer  length if you make
  189.       changes  to  the  EditBuffer  string  without  using  Pascal  strings
  190.       functions or procedures.
  191.  
  192.            The  reverse function (GetEditline) which stores the actual line
  193.       to the EditBuffer is always done automatically. So don't care.
  194.  
  195.  
  196.       AH = 2
  197.       ******
  198.  
  199.            On return ES:BX contains the address of the following block:
  200.  
  201.       AddOnLast      1 byte  Key down insert newline on last line flag
  202.       AlarmFlag      1 byte  Error beep flag
  203.       AsciiMode      1 byte  Control characters entry flag
  204.       AutoBackFlag   1 byte  Backspace behaviour flag
  205.       AutoSaveFlag   1 byte  Autosave flag
  206.       AutoScrollFlag 1 byte  Autoscroll flag
  207.       AutoTabFlag    1 byte  Autotab flag
  208.       BakFlag        1 byte  .BAK files generation flag
  209.       BlanksFlag     1 byte  Strip trailing spaces when saving flag
  210.       CompFlag       1 byte  Compression mode flag
  211.       Ega_Vga_OK     1 byte  43 lines mode flag
  212.       Flag35         1 byte  35 lines mode flag - EGA_VGA_OK must be on
  213.       LogFlag        1 byte  Log file flag
  214.       PauseMode      1 byte  Pause on return from DOS flag
  215.       ShiftFlag      1 byte  Accelerated cursor flag
  216.       Warning        1 byte  Warning before saving flag
  217.       Enter_Classic  1 byte  Split line using ENTER flag
  218.       RefreshFlag    1 byte  Display authorization
  219.  
  220.            There  is  only  two  possible values for each of these flags: 1
  221.       if the flag is TRUE and 0 if it is FALSE.
  222.  
  223.            These  flags  correspond to the equivalent commands described in
  224.       the E! documentation.
  225.  
  226.            Changing  Ega_Vga_Ok  and  Flag35 will not set the corresponding
  227.       display  mode.  These are only "authorization" flags. You have to use
  228.       Ctrl G (function code 7) to activate this modes.
  229.  
  230.  
  231.       AH = 3
  232.       ******
  233.  
  234.            On return ES:BX points to the following structure:
  235.  
  236.       Text_Attr        1 byte     Edited text attribute
  237.       BlockAttr        1 byte     Marked block attribute
  238.       CommandLineAttr  1 byte     Command line attribute
  239.       LoStatusLineAttr 1 byte     Status line 1 attribute
  240.       HiStatusLineAttr 1 byte     Status line 2 attribute
  241.       MessageAttr      1 byte     Messages attribute
  242.       HelpAttr         1 byte     Help line attribute
  243.       CursorAttr       1 byte     Virtual cursor attribute
  244.  
  245.            Please note the following:
  246.  
  247.            Changing  the  value  of  Text_Attr will NOT change the color of
  248.       the  edited  text  unless  you  call  the ResetMask service described
  249.       below (AH = 11). This applies to Text_Attr only.
  250.  
  251.  
  252.       AH = 4
  253.       ******
  254.  
  255.            On return ES:BX points to the following structure:
  256.  
  257.       ShiftKeyCount   2 bytes    Delay value for secondary help lines
  258.       AutoSaveLimit   2 bytes    Keystrokes # for autosave
  259.       ScrollAmountGlb 2 bytes    Left / Right scroll amount
  260.       DrawModel       2 bytes    Drawing style
  261.       LeftMargin      2 bytes    Left margin
  262.       ParMargin       2 bytes    New paragraph margin
  263.       RightMargin     2 bytes    Right margin
  264.  
  265.  
  266.       AH = 5
  267.       ******
  268.  
  269.            On return ES:BX points to the following structure:
  270.  
  271.       HelpLine1      81 bytes      4 Pascal strings
  272.        to
  273.       HelpLine4      81 bytes          "
  274.       ErrorMessage1  38 bytes     43 Pascal strings
  275.                     (43 bytes for the french version)
  276.        to
  277.       ErrorMessage43 43 bytes          "
  278.  
  279.            Normally  you  will  not  need  to access these message strings.
  280.       This service is only here for special needs.
  281.  
  282.  
  283.       AH = 6
  284.       ******
  285.  
  286.            On  return  ES:BX  points  to  the  "text flow" representing the
  287.       current  text  beeing edited. This pointer is actually the address of
  288.       an  array  of  pointers.  Each  of these pointers points to a line of
  289.       text,  that  is,  to a Pascal string representing a line of the text.
  290.       Array  indexes  are  actual  line  numbers.  So, the first element of
  291.       this  array  will  point to the first line in the current text and so
  292.       on...
  293.  
  294.            ES:BX ─────────> Ptr1 (4 bytes) ────────────> Line #1
  295.                             Ptr2 (4 bytes) ────────────> Line #2
  296.                             Ptr3 (4 bytes) ────────────> Line #3
  297.                             Ptr4 (4 bytes) ────────────> Line #4
  298.                             Ptr5 (4 bytes) ────────────> Line #5
  299.                             .....
  300.  
  301.            This  array  can be indexed up to the value returned in CX after
  302.       call #8. See AH = 8.
  303.  
  304.            This  call  is  made  to READ the text lines NOT TO CHANGE them.
  305.       There  is  no extra space allocated for each string and any change to
  306.       the  length  of the string without reallocating the memory used by it
  307.       will likely result in a system crash when your program returns to E!.
  308.  
  309.            To  make  changes  to  the  text,  access  the  lines  with a E!
  310.       cursor   positionning  function  or  with  function  call  number  14
  311.       (change  active  line).  The  EditBuffer  will  be  loaded  with  the
  312.       requested  line.  Modify  the  EditBuffer and then store the new line
  313.       to the text using the "Store Edit Line " call.
  314.  
  315.            E!  is  a  complex machinery. Please respect these rules to keep
  316.       your memory and your files safe.
  317.  
  318.  
  319.       AH = 7
  320.       ******
  321.  
  322.            On  return  ES:BX  points  to  a  Pascal string representing the
  323.       full name of the current file beeing edited.
  324.  
  325.  
  326.  
  327.       3/ Requesting screen status - AH = 8
  328.       ____________________________________
  329.  
  330.            On  return  the  cpu  registers  are  loaded  with some specific
  331.       values that are of great interest for the E! API programmer:
  332.  
  333.  
  334.            CX    contains the total number of lines in the current text
  335.            DX    contains the current line number (from 1 to CX)
  336.            AH    contains the cursor position (from 1 to 255)
  337.            AL    contains the value of the first displayed column
  338.            BH    contains the amount of lines displayed on the screen
  339.                  (25, 35, 43 or 50)
  340.            BL    contains the number of opened windows
  341.  
  342.            There is no return code for this function.
  343.  
  344.  
  345.       4/ Requesting special services - AH = 9 to 13
  346.       _____________________________________________
  347.  
  348.  
  349.       AH = 9
  350.       ******
  351.  
  352.            This  call  will  cause  E!  to  display the current editbuffer.
  353.       Modifying  the  editbuffer  does not modify the corresponding line on
  354.       the  screen. If you need to do so, you have to call this function. Be
  355.       aware  that this function DOES NOT store the EditBuffer to the actual
  356.       text. See AH = 12.
  357.  
  358.  
  359.       AH = 10
  360.       *******
  361.  
  362.            This call will cause E! to rebuild the whole screen.
  363.  
  364.  
  365.       AH = 11
  366.       *******
  367.  
  368.            This  call  will  reset  the  text  mask  using the new value of
  369.       Text_Attr.  The  text  mask  is a structure used by E! to display the
  370.       text when a window is refreshed.
  371.  
  372.  
  373.       AH = 12
  374.       *******
  375.  
  376.            This  function  will  cause  E!  to  store  the  content  of the
  377.       EditBuffer  to the actual text. PLEASE DO NOT try to do this yourself
  378.       using  the  value of the text flow pointer. The E! heap manager would
  379.       be fooled and an error would probably occur.
  380.  
  381.  
  382.       AH = 13
  383.       *******
  384.  
  385.            This  function  sets  the  current  text  "change flag" to TRUE.
  386.       Please use it if you have made any change to the current text.
  387.  
  388.           ┌────────────────────────────────────────────┐
  389.           │There is no return code for these functions.│
  390.           └────────────────────────────────────────────┘
  391.  
  392.  
  393.       5/ Changing the active line - AH = 14
  394.       _____________________________________
  395.  
  396.  
  397.       AH = 14
  398.       *******
  399.  
  400.            If  the  value  passed  in  BX is a valid line number, this line
  401.       becomes  the  active  line  and  also the first displayed line in the
  402.       active  window.  Likewise,  the  value passed in AL indicates the new
  403.       cursor  position  on  the  new  line and also the new first displayed
  404.       column.  This  will  avoid  consistency problems beetween display and
  405.       cursor  position.  If  either BX or AL contains 0 on entry, no action
  406.       is  taken  regarding  the  corresponding  parameter. The other one is
  407.       processed  normally.  Otherwise  AL  will contain FFh on exit or 0 if
  408.       the  operation  succeeded.  The Editbuffer is loaded with the content
  409.       of  the  new  line.  Its  previous content is automatically stored to
  410.       the line that was active when this call was made.
  411.  
  412.            This  is  the  call  you  have  to  use  if you want to directly
  413.       modify the current text.
  414.  
  415.  
  416.  
  417.       6/ Requesting E! version - AH = 15
  418.       __________________________________
  419.  
  420.            On  return  AH  will contain the "major" digit of the E! version
  421.       and  AL  will  contain  the minor digit. i.e. for version 4.0 AH will
  422.       return 4 and AL will return 0.
  423.  
  424.  
  425.  
  426.       7/ Registering a E! command - AH = 16
  427.       _____________________________________
  428.  
  429.            As  stated  below  it  is  not  possible  to execute E! commands
  430.       (commands  entered  on the E! command line) from an external program.
  431.       The  main  reason  for that is that the command processor code is not
  432.       and CANNOT be reentrant.
  433.  
  434.            However  you  may  need  to  request a command execution. The E!
  435.       API  offers  a  limited  way  of executing a command from an external
  436.       program.  Your  API  program  may  "register"  a  command  using call
  437.       number   16.  When  the  API  program  EXITS,  the  command  will  be
  438.       executed.   You  may  register  the  command  anywhere  in  your  API
  439.       program.  You  may  register only one command. Though if you register
  440.       several commands,  only the last one will be executed.
  441.  
  442.            To  register  a command you have to pass the address of a Pascal
  443.       string  representing  the command exactly as if you entered it on the
  444.       E!  command line, in the ES:BX registers pair. Then call INT C0h with
  445.       AH set to 16. That's all.
  446.  
  447.            Please  note  that  this  call  allows  you  to easily chain API
  448.       programs. The registered command may be a call to another API program
  449.       and so on...
  450.  
  451.            The  P! program is an example of what can be achieved using this
  452.       call.  This  program  allows you to choose a file from a pick list to
  453.       have  it edited. The P! source file contains copyrighted material, so
  454.       it cannot be released. However it is easy to understand that once the
  455.       filename  has been choosen from the pick list, it can be passed along
  456.       with  the  EDIT  command  using  call number 16. When the API program
  457.       returns, the file will be loaded.
  458.  
  459.  
  460.  
  461.       The REFRESH flag
  462.       ****************
  463.  
  464.            By   default,  E!  will  automatically  refresh  the  screen  if
  465.       necessary  after  each  function  call  (AH  =  0).  If you find this
  466.       somewhat  tedious  or  if you want to spare time, you may disable the
  467.       screen  refresh  process  by setting the REFRESH flag to FALSE before
  468.       the  function  calls  are  made  and resetting it to TRUE after these
  469.       calls.  You  MUST  reset  this  flag  to  TRUE  before  your  program
  470.       terminates.  If  you  fail  to  do  so, E! will do it for you if your
  471.       program  has  been  loaded  with  the "@" prefix. The REFRESH flag is
  472.       accessed  thru  the  call  number  2.  This  is  the last flag of the
  473.       structure.
  474.  
  475.  
  476. C. THE HEAP MANAGEMENT
  477. **********************
  478.  
  479.            You  may  wonder  how  E!  manage the memory to allow you to use
  480.       the  full  system memory when no external program is active and still
  481.       allow  E!  functions  to  execute  when  the same external program is
  482.       loaded  on  the  top  of E! even if these functions make an extensive
  483.       use  of  the heap. This is one of the E! programming secrets. However
  484.       the  user  has  to  control the memory amount left between E! and the
  485.       API program.
  486.  
  487.            If  your  program  only  changes  variables  values  or  call E!
  488.       functions  that  do  not  make  use  of  the heap, you may leave this
  489.       value  unchanged  (it  defaults  to 256 paragraphs) or even set it to
  490.       0.  Though  there  is  very  few E! functions that do not make use of
  491.       the  heap  or  that  do  not  call  a  subroutine  that uses the heap
  492.       itself.  So  it  will  be  almost  always  necessary to preserve some
  493.       space for the E! heap before calling the API program .
  494.  
  495.            This is done using a command in the E! main profile:
  496.  
  497.            HEAP n
  498.  
  499.            n  representing  the number of PARAGRAPHS (16 bytes) you want to
  500.       preserve.  The  value  you  will  use will highly depend on what your
  501.       program  actually  does and what E! functions it calls. The E! MEMORY
  502.       command  will  always  show  you  the amount of free memory available
  503.       for  your  program to run. Substract from this value the memory space
  504.       needed   by   your   program  plus  a  security  and  you  will  have
  505.       approximately  the  value  to  pass  to  the  HEAP  command  in  your
  506.       profile.
  507.  
  508.            It  is  allowed to set the HEAP parameter to 0 if you don't need
  509.       the E! API.
  510.  
  511.            This  space  is  reserved  whatever the command you used to make
  512.       the dos shell, that is, even if you did not use the "@" prefix.
  513.  
  514.            If  there  not enough memory space reserved for the E! functions
  515.       your  program  calls,  E!  will  behave  exactly the same as if these
  516.       commands  have  been  launched  from the keyboard. So you will get an
  517.       error  message  and  so  on... If your program fails because it lacks
  518.       memory space, try a greater value for the HEAP command parameter.
  519.  
  520.  
  521.  
  522. D. AN API EXAMPLE
  523. *****************
  524.  
  525.            The  API.PAS  file  provided  with  the  API documentation is an
  526.       example  of  an implementation of a turbo pascal UNIT interfacing the
  527.       E!  API. Reading this commented code will help you understand how the
  528.       API works.
  529.  
  530.  
  531.  
  532. E. CONCLUSION
  533. *************
  534.  
  535.            If you want to write your own menu or complex macros or whatever
  536.       function  you will find useful you have now a simple to use interface
  537.       to  E!. It is highly recommended that programs written for the E! API
  538.       be called with the "@" prefix from the E! command line.
  539.  
  540.            It  is  up to the API programmer to make sure that the E! screen
  541.       is  not  destroyed  during program execution. E! does not refresh the
  542.       screen  when  it  returns  from  a  child process called with the "@"
  543.       prefix.
  544.  
  545.            You  may  wonder  why  there  is  no  provision in the E! API to
  546.       execute  a  E!  command  exactly as if you typed it on the E! command
  547.       line.  The  answer  is quite obvious : a E! command can also be a DOS
  548.       command.  Imagine  your  API  program  is executing and you ask E! to
  549.       execute another child process...
  550.  
  551.       Have fun!
  552.  
  553.  
  554. Patrick Philippot 12/16/1988
  555.